using System;
using System.Diagnostics;
using System.Collections.Generic;

//svnkit imports
using org.tmatesoft.svn.core;
using org.tmatesoft.svn.core.wc;

namespace Subsync.Core.Subversion
{
    class SVNLock : CommandBase
    {
        // Initialise variables with default settings.
        int no_of_filepath;
        public java.io.File[] file_path; //url of file to be locked
        bool stealLock = true; //other users may take over the lock
        string lockMessage; //compulsory field

        // Minimal constructor1.
        public SVNLock(string strpath, string message)
        {
            Debug.WriteLine("SVN Lock minimal Constructor with defaults");
            List<string> path = new List<string>();
            path.Add(strpath);
            this.constructSVNLock(path, true, message);
        }

        // Minimal constructor2.
        public SVNLock(List<string> path, string message)
        {
            Debug.WriteLine("SVN Lock minimal Constructor with defaults");

            this.constructSVNLock(path, true, message);
        }

        // Full constructor
        public SVNLock(List<string> path, bool stealLock, string message)
        {
            Debug.WriteLine("SVN Lock full Constructor with defaults");

            constructSVNLock(path, stealLock, message);
        }

        public void constructSVNLock(List<string> path, bool stealLock, string message)
        {
            this.lockMessage = message;
            this.stealLock = stealLock;
            this.file_path = new java.io.File[path.Count];
            for (int i = 0; i < path.Count; i++)
                file_path[i] = new java.io.File(path[i]);
        }

        public override void Execute()
        {
            Debug.WriteLine("SVN Lock Execution");

            //library setup
            Tools.setupLibrary();

            //load up the clients
            SVNClientManager cm = SVNClientManager.newInstance();
            SVNWCClient wc = cm.getWCClient();

            try
            {
                wc.doLock(this.file_path, this.stealLock, this.lockMessage);
            }
            catch (SVNException e)
            {
                //we convert this exception to a non SVNKit exception.
                //we want to minimize interfacing with SVNkit outside of this namespace (abstraction)
                throw new SVNExecuteException(e.getMessage());
            }
        }

        public override Dictionary<string, List<object>> getTokens ()
		{
			Dictionary<string, List<object>> ret = new Dictionary<string, List<object>> ();
			ret.Add("Lock",new List<object>() {"lk","lock"});
			return ret;
		}
		
		public override List<KeyValuePair<string,initPointer>> getInitPointers() {
			List<KeyValuePair<string,initPointer>> ret = new List<KeyValuePair<string,initPointer>>();
			ret.Add(new KeyValuePair<string,initPointer>("Lock",new initPointer(this.handleCLI)));
			return ret;
		}
		
		public void handleCLI(Dictionary<string,List<object>> tokens) {
            no_of_filepath = tokens["Lock"].Count - 1;
			if (no_of_filepath != 1) {
				Console.WriteLine("Not enough arguments: Lock requires at least 2 argument (url, message)");
				return;
			}
            List<string> path = new List<string>();
            for (int i = 0; i < no_of_filepath; i++)
                path.Add((string)tokens["Lock"][i]);
            string message = (string) tokens["Lock"][no_of_filepath];
			this.constructSVNLock(path, true, message);
            this.Execute();
        }

        public SVNLock() {}
    }
}
